{% extends "base.html" %}

{% block title %}数据展示系统 - 实时搜索{% endblock %}
{% block page_title %}数据接收概览与搜索{% endblock %}

{# 移除此 block，使用 base.html 的默认导航链接，并利用 base.html 的 active 逻辑 #}
{# 如果您希望覆盖 base.html 的导航，请取消注释并按需修改 #}
{#
{% block nav_links %} 
    <a href="{{ url_for('index') }}" class="active">首页</a>
    <a href="{{ url_for('map_page') }}">地图</a>
{% endblock %}
#}

{% block head %}
    {{ super() }}
    <!-- Flatpickr CSS -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css">
    <!-- 如果需要主题，例如 material_blue -->
    {# <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/themes/material_blue.css"> #}
    <style>
        /* 基础布局和间距 */
        body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; line-height: 1.6; color: #333; background-color: #f8f9fa; }
        .container { max-width: 1200px; margin: 20px auto; padding: 0 15px; }
        h1, h2, h3, h4, h5, h6 { color: #343a40; margin-bottom: 15px; }
        label { font-weight: bold; margin-bottom: 5px; display: block; color: #555; }
        input[type="text"], select {
            width: 100%;
            padding: 10px 12px;
            margin-bottom: 15px;
            border: 1px solid #ced4da;
            border-radius: 4px;
            box-sizing: border-box;
            font-size: 1rem;
            color: #495057;
            background-color: #fff;
            transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
        }
        input[type="text"]:focus, select:focus {
            border-color: #80bdff;
            outline: 0;
            box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);
        }
        select[multiple] { height: auto; min-height: 100px; }

        /* 搜索和筛选控件 */
        .search-controls {
            background-color: #ffffff;
            border: 1px solid #e0e0e0;
            border-radius: 8px;
            padding: 20px;
            margin-bottom: 25px;
            box-shadow: 0 2px 5px rgba(0,0,0,0.05);
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); /* 响应式列 */
            gap: 20px;
        }
        .search-controls > div {
            display: flex;
            flex-direction: column;
        }
        .full-width { /* 针对时间选择器及其按钮组 */
            grid-column: 1 / -1; /* 跨越所有列 */
        }
        .button-group {
            display: flex;
            gap: 10px;
            flex-wrap: wrap; /* 按钮组在小屏幕上可换行 */
        }
        .button {
            padding: 8px 15px;
            border: 1px solid #007bff;
            border-radius: 4px;
            cursor: pointer;
            font-size: 0.9rem;
            transition: all 0.2s ease-in-out;
            white-space: nowrap; /* 避免按钮文字换行 */
        }
        .button.primary { background-color: #007bff; color: white; border-color: #007bff; }
        .button.primary:hover { background-color: #0056b3; border-color: #0056b3; }
        .button.secondary { background-color: #6c757d; color: white; border-color: #6c757d; }
        .button.secondary:hover { background-color: #5a6268; border-color: #5a6268; }
        .button.small { padding: 6px 12px; font-size: 0.85rem; }
        .button.outline-primary { background-color: white; color: #007bff; border-color: #007bff; }
        .button.outline-primary:hover { background-color: #007bff; color: white; }

        /* 汇总统计区域 */
        .summary-stats {
            display: flex;
            justify-content: flex-start; /* 左对齐 */
            gap: 30px; /* 增加间距 */
            margin-bottom: 25px;
            padding-left: 10px; /* 与搜索框对齐 */
        }
        .summary-item {
            text-align: center;
            padding: 10px 0;
        }
        .summary-item .value {
            font-size: 2.2em; /* 增大数字 */
            font-weight: bold;
            color: #28a745; /* 绿色，表示积极的统计 */
            margin-bottom: 5px;
        }
        .summary-item .label {
            font-size: 0.9em;
            color: #6c757d;
        }

        /* 消息提示 */
        .no-data-message {
            background-color: #e2e3e5;
            color: #383d41;
            padding: 15px;
            margin-bottom: 20px;
            border: 1px solid #d6d8db;
            border-radius: 5px;
            text-align: center;
            font-size: 1.1em;
        }
        .no-data-message.error {
            background-color: #f8d7da;
            color: #721c24;
            border-color: #f5c6cb;
        }
        .no-data-message.hidden { display: none !important; }

        /* ID 分组卡片样式 */
        .id-group {
            background-color: #ffffff;
            border: 1px solid #e0e0e0;
            border-radius: 8px;
            margin-bottom: 20px;
            box-shadow: 0 2px 5px rgba(0,0,0,0.05);
            overflow: hidden; /* 确保子元素不会超出圆角 */
        }
        .id-group-header {
            background-color: #f0f0f0;
            padding: 15px 20px;
            border-bottom: 1px solid #e0e0e0;
            display: flex;
            justify-content: space-between;
            align-items: center;
            font-size: 1.1em;
            font-weight: bold;
            cursor: pointer;
            user-select: none; /* 防止文本被选中 */
        }
        .id-group-header:hover {
            background-color: #e9e9e9;
        }
        .id-text {
            color: #007bff; /* 强调 ID */
        }
        .id-group-toggle-icon {
            margin-left: 10px;
            transition: transform 0.2s ease-in-out;
        }
        .id-group-toggle-icon.rotated {
            transform: rotate(-90deg);
        }
        .id-group-content {
            padding: 0 20px; /* 仅在展开时显示内边距 */
            max-height: 10000px; /* 足够大的值来模拟无限高度 */
            overflow: hidden;
            transition: max-height 0.3s ease-in-out, padding 0.3s ease-in-out;
        }
        .id-group-content.collapsed {
            max-height: 0;
            padding-top: 0;
            padding-bottom: 0;
        }

        /* 消息卡片样式 */
        .message-card {
            background-color: #ffffff;
            border: 1px solid #dee2e6;
            border-radius: 6px;
            margin: 15px 0; /* 在 ID group 内部，卡片之间有间距 */
            box-shadow: 0 1px 3px rgba(0,0,0,0.08);
            overflow: hidden;
        }
        .message-card-header {
            background-color: #f8f9fa;
            padding: 12px 15px;
            border-bottom: 1px solid #e9ecef;
            display: flex;
            justify-content: space-between;
            align-items: center;
            font-size: 0.95em;
            cursor: pointer;
            user-select: none;
            color: #343a40;
        }
        .message-card-header:hover {
            background-color: #eaf0f6;
        }
        .message-card-header .toggle-icon {
            margin-left: 10px;
            transition: transform 0.2s ease-in-out;
        }
        .message-card-header .toggle-icon.rotated {
            transform: rotate(-90deg);
        }
        .message-card-body {
            padding: 15px;
            max-height: 1000px; /* 大值，用于动画 */
            overflow: hidden;
            transition: max-height 0.3s ease-in-out, padding 0.3s ease-in-out;
        }
        .message-card-body.collapsed {
            max-height: 0;
            padding-top: 0;
            padding-bottom: 0;
        }
        .message-card-body p {
            margin-bottom: 8px;
            font-size: 0.9em;
            color: #495057;
        }
        .message-card-body strong {
            color: #343a40;
            display: inline-block; /* 保持与值对齐 */
            min-width: 80px; /* 统一 label 宽度 */
        }
        .message-card-body .value-text {
            word-break: break-all; /* 防止长字符串溢出 */
        }
        .message-card-body .custom-data {
            border-top: 1px dashed #e9ecef;
            margin-top: 10px;
            padding-top: 10px;
            font-style: italic;
            color: #6c757d;
        }
        .message-card-body .custom-data strong {
            color: #555;
        }

        /* 搜索高亮 */
        .highlight {
            background-color: #ffe08a; /* 亮黄色背景 */
            padding: 0 2px;
            border-radius: 3px;
            font-weight: bold; /* 加粗 */
            color: #333; /* 确保文字清晰 */
        }

        /* 查看历史按钮 */
        .view-history-button {
            background-color: #17a2b8; /* 信息蓝色 */
            color: white;
            border: none;
            padding: 6px 12px;
            border-radius: 4px;
            cursor: pointer;
            font-size: 0.85em;
            margin-top: 10px;
            transition: background-color 0.2s;
            display: block; /* 独立一行 */
            width: fit-content; /* 宽度适应内容 */
        }
        .view-history-button:hover {
            background-color: #138496;
        }
        .view-history-button:disabled {
            background-color: #cccccc;
            cursor: not-allowed;
        }

        /* 响应式调整 */
        @media (max-width: 768px) {
            .search-controls {
                grid-template-columns: 1fr; /* 单列布局 */
            }
            .full-width {
                grid-column: auto;
            }
            .summary-stats {
                flex-direction: column;
                align-items: flex-start;
                gap: 15px;
            }
            .summary-item {
                width: 100%;
                text-align: left;
            }
            .message-card-header {
                flex-direction: column;
                align-items: flex-start;
                gap: 5px;
            }
        }
    </style>
{% endblock %}

{% block content %}
    <div class="search-controls">
        <div>
            <label for="searchQuery">内容搜索</label>
            <input type="text" id="searchQuery" placeholder="输入关键词 (ID, 定位时间, 经纬度, 自定义数据等)">
        </div>
        <div>
            <label for="searchIdNumber">筛选ID</label>
            {# 新增的 ID 筛选下拉列表 #}
            <select id="searchIdNumber">
                <option value="">所有ID</option>
                {% for id_option in display_id_options %}
                    <option value="{{ id_option.original_id }}">{{ id_option.display_name }}</option>
                {% endfor %}
            </select>
        </div>
        {# 更改：添加了新的按钮组，并调整了 full-width div 的内部结构 #}
        <div class="full-width"> 
            <label for="receiveTimeRange">接收时间范围</label>
            {# 使用 Flatpickr 输入框 #}
            <input type="text" id="receiveTimeRange" placeholder="选择时间范围">
            <div class="button-group" style="margin-top: 10px;">
                <button type="button" class="button secondary small" id="clearTimeRange">全部时间</button>
                <button type="button" class="button secondary small" id="selectToday">今天</button>
                <button type="button" class="button secondary small" id="selectLastMonth">最近一月</button>
            </div>
        </div>
    </div>

    <div class="summary-stats">
        <div class="summary-item">
            <div class="value" id="displayedIdCount">{{ unique_id_count_total }}</div> {# 初始显示总的唯一显示ID数量 #}
            <div class="label">显示卡号数量</div>
        </div>
        <div class="summary-item">
            <div class="value" id="displayedMessageCount">{{ total_messages_count_total }}</div> {# 初始显示总的消息数量 #}
            <div class="label">显示消息总数</div>
        </div>
    </div>

    {# 消息提示区域 #}
    <div id="loadingIndicator" class="no-data-message" style="display: none;">
        加载中...
    </div>
    <div id="jsError" class="no-data-message error" style="display: none;">
        前端脚本发生错误，请查看浏览器控制台 (F12) 获取详情。
    </div>
    <div id="noSearchResults" class="no-data-message" style="display: none;">
        未找到匹配的数据。请尝试调整搜索条件。
    </div>
    <div id="initialNoData" class="no-data-message {% if total_messages_count_total > 0 %}hidden{% else %}block{% endif %}" >
        目前没有接收到任何数据。等待设备上报数据或刷新页面。
    </div>
    
    <div id="messagesContainer">
        <!-- 消息卡片将在这里通过 JavaScript 渲染 -->
    </div>

    <!-- Flatpickr JS -->
    <script src="https://cdn.jsdelivr.net/npm/flatpickr"></script>
    <!-- Flatpickr 简体中文语言包 -->
    <script src="https://cdn.jsdelivr.net/npm/flatpickr/dist/l10n/zh.js"></script>

    <script>
        console.log('--- Frontend Debugging Start: Script Loaded (index.html) ---');
        document.getElementById('jsError').style.display = 'none';

        // 接收所有 ID 的所有消息 (已在后端格式化)
        // 结构: { "原始ID": [formatted_msg1, formatted_msg2, ...], "原始ID2": [...] }
        const allMessagesGroupedById = {{ all_messages_grouped_by_id | tojson }};
        // 接收用于下拉列表的 ID 选项，包含 display_name 和 original_id
        const displayIdOptions = {{ display_id_options | tojson }};

        console.log('Received allMessagesGroupedById (JavaScript object from Flask): ', allMessagesGroupedById);
        console.log('Received displayIdOptions:', displayIdOptions);

        const messagesContainer = document.getElementById('messagesContainer');
        const searchQueryInput = document.getElementById('searchQuery');
        const searchIdNumberSelect = document.getElementById('searchIdNumber'); // 新增
        const receiveTimeRangeInput = document.getElementById('receiveTimeRange'); // Flatpickr input
        const noSearchResultsDiv = document.getElementById('noSearchResults');
        const initialNoDataDiv = document.getElementById('initialNoData');
        const displayedIdCountSpan = document.getElementById('displayedIdCount');
        const displayedMessageCountSpan = document.getElementById('displayedMessageCount');

        // 新增的按钮元素
        const clearTimeRangeButton = document.getElementById('clearTimeRange');
        const selectTodayButton = document.getElementById('selectToday');
        const selectLastMonthButton = document.getElementById('selectLastMonth');

        // Flatpickr 实例变量
        let receiveTimeFlatpickrInstance;
        
        document.addEventListener('DOMContentLoaded', () => {
            // 在这里初始化 Flatpickr，并设置 onChange。
            // 这样确保 index.html 拥有对该实例的完全控制。
            receiveTimeFlatpickrInstance = flatpickr(receiveTimeRangeInput, {
                mode: "range",
                dateFormat: "Y-m-d H:i:S",
                enableTime: true,
                time_24hr: true,
                locale: "zh",
                onChange: function(selectedDates, dateStr, instance) {
                    console.log("Flatpickr onChange triggered:", dateStr);
                    // dateStr: "YYYY-MM-DD HH:mm:SS to YYYY-MM-DD HH:mm:SS" (英文to)
                    // instance.input.value: "YYYY-MM-DD HH:mm:SS 至 YYYY-MM-DD HH:mm:SS" (中文至)
                    // 我们将使用 selectedDates 来生成用于过滤的日期字符串
                    renderMessages(); // Flatpickr 值改变时重新渲染
                }
            });
            
            // 页面加载完成后立即渲染一次消息
            renderMessages();

            // 绑定新按钮的事件监听器
            clearTimeRangeButton.addEventListener('click', () => {
                receiveTimeFlatpickrInstance.clear(); // 清空日期选择，会触发 onChange
            });

            selectTodayButton.addEventListener('click', () => {
                const today = new Date();
                const startOfToday = new Date(today.getFullYear(), today.getMonth(), today.getDate(), 0, 0, 0);
                const endOfToday = new Date(today.getFullYear(), today.getMonth(), today.getDate(), 23, 59, 59, 999); // 确保包含当天所有时间点
                receiveTimeFlatpickrInstance.setDate([startOfToday, endOfToday], true); // true 触发 onChange
                console.log("Setting date to 'Today':", startOfToday.toISOString(), "-", endOfToday.toISOString());
            });

            selectLastMonthButton.addEventListener('click', () => {
                const today = new Date();
                const endOfToday = new Date(today.getFullYear(), today.getMonth(), today.getDate(), 23, 59, 59, 999); // 确保包含当天所有时间点
                
                // --- 修正“最近一月”的起始日期计算：更健壮的逻辑 ---
                const startOfLastMonth = new Date(today); // 复制当前日期
                const currentDay = today.getDate(); // 获取当前日期的天数 (例如 31)
                
                startOfLastMonth.setDate(1); // 先将日期设置为当月1号，避免 setMonth 溢出
                startOfLastMonth.setMonth(today.getMonth() - 1); // 然后减去一个月
                
                // 再将日期设置为原始的 'currentDay'，但不能超过上个月的实际天数
                const daysInLastMonth = new Date(startOfLastMonth.getFullYear(), startOfLastMonth.getMonth() + 1, 0).getDate();
                startOfLastMonth.setDate(Math.min(currentDay, daysInLastMonth));
                
                startOfLastMonth.setHours(0, 0, 0, 0); // 设置为当天的0点0分0秒
                // --- 修正结束 ---

                receiveTimeFlatpickrInstance.setDate([startOfLastMonth, endOfToday], true); // true 触发 onChange
                console.log("Setting date to 'Last Month':", startOfLastMonth.toISOString(), "-", endOfToday.toISOString());
            });
        });

        // 辅助函数：将文本中的搜索关键词高亮显示
        function highlightText(text, query) {
            if (!query || !text) {
                return text;
            }
            const lowerCaseText = String(text).toLowerCase();
            const lowerCaseQuery = String(query).toLowerCase();
            
            let result = [];
            let lastIndex = 0;
            let match;

            // 使用正则表达式进行全局和不区分大小写匹配
            const regex = new RegExp(lowerCaseQuery, 'gi');

            while ((match = regex.exec(text)) !== null) {
                // 添加匹配前的文本
                if (match.index > lastIndex) {
                    result.push(text.substring(lastIndex, match.index));
                }
                // 添加高亮文本
                result.push('<span class="highlight">' + text.substring(match.index, regex.lastIndex) + '</span>');
                lastIndex = regex.lastIndex;
            }

            // 添加匹配后的剩余文本
            if (lastIndex < text.length) {
                result.push(text.substring(lastIndex));
            }
            return result.join('');
        }

        // 辅助函数：判断消息是否匹配搜索查询
        function messageMatchesQuery(msg, query) {
            if (!query) return true;

            const lowerCaseQuery = query.toLowerCase();

            // 检查原始 ID Number
            if (String(msg['IdNumber']).toLowerCase().includes(lowerCaseQuery)) return true;
            // 检查显示 ID 名称
            if (String(msg['display_id_name']).toLowerCase().includes(lowerCaseQuery)) return true;
            // 检查 MessageId
            if (String(msg['MessageId']).toLowerCase().includes(lowerCaseQuery)) return true;
            // 检查接收时间
            if (String(msg['接收时间']).toLowerCase().includes(lowerCaseQuery)) return true;
            // 检查定位时间
            if (String(msg['定位时间']).toLowerCase().includes(lowerCaseQuery)) return true;
            // 检查纬度
            if (String(msg['纬度']).toLowerCase().includes(lowerCaseQuery)) return true;
            // 检查经度
            if (String(msg['经度']).toLowerCase().includes(lowerCaseQuery)) return true;
            // 检查高程
            if (String(msg['高程']).toLowerCase().includes(lowerCaseQuery)) return true;
            // 检查自定义数据
            if (String(msg['自定义数据']).toLowerCase().includes(lowerCaseQuery)) return true;
            // 检查浮标标识名字
            if (String(msg['浮标标识名字']).toLowerCase().includes(lowerCaseQuery)) return true;
            // 检查原始POST数据
            if (msg['raw_post_data_json'] && String(JSON.stringify(msg['raw_post_data_json'])).toLowerCase().includes(lowerCaseQuery)) return true; // 注意这里需要stringify
            
            return false;
        }

        // 辅助函数：判断消息是否匹配日期时间范围
        // >>> 关键修改点1: 函数签名修改为接收两个独立的日期字符串 <<<
        function messageMatchesDateRange(msg, filterStartDateStr, filterEndDateStr) {
            // 如果任何一个日期字符串为空，则视为没有日期范围限制，所有消息都匹配
            if (!filterStartDateStr || !filterEndDateStr) {
                return true;
            }

            const receiveTime = msg['接收时间']; // 使用 '接收时间' 字段进行过滤
            if (!receiveTime) return false;

            try {
                // messageDate 应该能够解析各种 ISO 格式，包括带毫秒的
                const messageDate = new Date(receiveTime); 
                if (isNaN(messageDate.getTime())) {
                    console.warn("Invalid message receive time format:", receiveTime);
                    return false;
                }

                // >>> 关键修改点2: 直接使用传入的独立的 start/end 字符串进行 Date 对象转换 <<<
                const startDate = new Date(filterStartDateStr);
                const endDate = new Date(filterEndDateStr);
                
                if (isNaN(startDate.getTime())) { console.warn("Invalid start date string in comparison:", filterStartDateStr); return false; }
                if (isNaN(endDate.getTime())) { console.warn("Invalid end date string in comparison:", filterEndDateStr); return false; }

                // 检查消息日期是否在范围内（包含起始和结束日期）
                if (messageDate < startDate || messageDate > endDate) { 
                    return false;
                }
                return true;
            } catch (e) {
                console.error("日期时间解析错误 (messageMatchesDateRange):", e, "Receive Time:", receiveTime, "Start Date String:", filterStartDateStr, "End Date String:", filterEndDateStr);
                return false;
            }
        }

        // 辅助函数：创建单个消息卡片的 HTML
        function createMessageCardHtml(originalId, msg, searchQuery, defaultExpanded, isHistoryView, totalMessagesForId) {
            // 处理显示经纬度格式
            const formatLatLon = (direction, degrees, minutes) => {
                if (!degrees || !minutes) return `未知 ${direction}`;
                return `${direction}${degrees}°${minutes}'`;
            };

            const formattedLatitude = formatLatLon(msg['纬度半球'], msg['纬度度'], msg['纬度分']);
            const formattedLongitude = formatLatLon(msg['经度半球'], msg['经度度'], msg['经度分']);

            // 检查自定义数据是否有浮标标识
            const buoyName = msg['浮标标识名字'];
            const customDataDisplay = buoyName ? `${msg['自定义数据']} (浮标: ${buoyName})` : msg['自定义数据'];

            // 高亮处理
            const highlightedReceiveTime = highlightText(msg['接收时间'], searchQuery);
            const highlightedMessageId = highlightText(msg['MessageId'], searchQuery);
            const highlightedLocationTime = highlightText(msg['定位时间'], searchQuery);
            const highlightedLatitude = highlightText(formattedLatitude, searchQuery);
            const highlightedLongitude = highlightText(formattedLongitude, searchQuery);
            const highlightedElevation = highlightText(msg['高程'], searchQuery);
            const highlightedCustomData = highlightText(customDataDisplay, searchQuery);
            const highlightedNetworkMode = highlightText(msg['NetworkMode'], searchQuery);
            const highlightedContent = highlightText(msg['Content'], searchQuery);

            const cardCollapsedClass = defaultExpanded ? '' : 'collapsed';
            const toggleIconClass = defaultExpanded ? '' : 'rotated';

            // 查看历史按钮只在非搜索模式且非历史视图，且有超过一条消息时显示
            const showViewHistoryButton = !searchQuery && !isHistoryView && totalMessagesForId > 1;

            return `
                <div class="message-card" data-original-id="${originalId}" data-message-id="${msg.MessageId}">
                    <div class="message-card-header">
                        <div>
                            <strong>接收时间:</strong> <span class="value-text">${highlightedReceiveTime}</span> 
                            <strong>消息ID:</strong> <span class="value-text">${highlightedMessageId}</span>
                        </div>
                        <span class="toggle-icon ${toggleIconClass}">▼</span>
                    </div>
                    <div class="message-card-body ${cardCollapsedClass}">
                        <p><strong>定位时间:</strong> <span class="value-text">${highlightedLocationTime}</span></p>
                        <p><strong>经度:</strong> <span class="value-text">${highlightedLongitude}</span></p>
                        <p><strong>纬度:</strong> <span class="value-text">${highlightedLatitude}</span></p>
                        <p><strong>高程:</strong> <span class="value-text">${highlightedElevation} 米</span></p>
                        <p><strong>网络模式:</strong> <span class="value-text">${highlightedNetworkMode}</span></p>
                        <p class="custom-data"><strong>自定义数据:</strong> <span class="value-text">${highlightedCustomData}</span></p>
                        <p><strong>原始内容:</strong> <span class="value-text">${highlightedContent}</span></p>
                        <p><strong>完整POST数据:</strong> <span class="value-text" style="font-family: monospace; font-size: 0.8em; color: #666;">${highlightText(JSON.stringify(msg['raw_post_data_json']), searchQuery)}</span></p>
                        ${showViewHistoryButton ? `<button class="view-history-button" data-id="${originalId}">查看该ID历史消息 (${totalMessagesForId}条)</button>` : ''}
                    </div>
                </div>
            `;
        }

        // 绑定消息卡片折叠事件
        function bindCardToggleEvents() {
            document.querySelectorAll('.message-card-header').forEach(header => {
                header.removeEventListener('click', toggleCard); // 移除旧的，避免重复绑定
                header.addEventListener('click', toggleCard);
            });
        }

        function toggleCard(event) {
            const header = event.currentTarget;
            const body = header.nextElementSibling;
            const icon = header.querySelector('.toggle-icon');
            
            if (body && icon) {
                body.classList.toggle('collapsed');
                icon.classList.toggle('rotated');
            }
        }

        // 绑定 ID 分组折叠事件
        function bindIdGroupToggleEvents() {
            document.querySelectorAll('.id-group-header').forEach(header => {
                header.removeEventListener('click', toggleIdGroup); // 移除旧的，避免重复绑定
                header.addEventListener('click', toggleIdGroup);
            });
        }

        function toggleIdGroup(event) {
            const header = event.currentTarget;
            const content = header.nextElementSibling; // id-group-content
            const icon = header.querySelector('.id-group-toggle-icon');

            if (content && icon) {
                content.classList.toggle('collapsed');
                icon.classList.toggle('rotated');
            }
        }

        // 绑定查看历史消息按钮事件
        function bindViewHistoryEvents() {
            document.querySelectorAll('.view-history-button').forEach(button => {
                button.removeEventListener('click', viewHistory); // 移除旧的，避免重复绑定
                button.addEventListener('click', viewHistory);
            });
        }

        function viewHistory(event) {
            const originalId = event.currentTarget.dataset.id;
            console.log('Viewing history for ID:', originalId);
            // 这里我们不是跳转页面，而是在当前页面切换到“历史模式”
            // 简单实现：将筛选 ID 设为当前 ID，清空搜索框，清空时间范围，然后强制渲染所有该 ID 的消息
            searchIdNumberSelect.value = originalId;
            searchQueryInput.value = '';
            receiveTimeFlatpickrInstance.clear(); // 清空时间范围，会触发 onChange，进而触发 renderMessages

            // 强制渲染，确保显示所有历史
            renderMessages(true); // 传入一个标志，表示是历史视图
        }

        function renderMessages(isHistoryMode = false) {
            console.log('--- renderMessages called (index.html) ---');
            const query = searchQueryInput.value.trim(); 
            const lowerCaseQuery = query.toLowerCase();
            const selectedOriginalId = searchIdNumberSelect.value;
            
            // >>> 关键修改点3: 从 Flatpickr 实例的 selectedDates 属性获取日期对象，并格式化 <<<
            let filterStartDateStr = null;
            let filterEndDateStr = null;

            const selectedDates = receiveTimeFlatpickrInstance.selectedDates;
            if (selectedDates.length === 2) {
                filterStartDateStr = receiveTimeFlatpickrInstance.formatDate(selectedDates[0], "Y-m-d H:i:S");
                filterEndDateStr = receiveTimeFlatpickrInstance.formatDate(selectedDates[1], "Y-m-d H:i:S");
            } else if (selectedDates.length === 1) {
                // 如果只选择了一个日期，则视为当天
                filterStartDateStr = receiveTimeFlatpickrInstance.formatDate(selectedDates[0], "Y-m-d 00:00:00");
                filterEndDateStr = receiveTimeFlatpickrInstance.formatDate(selectedDates[0], "Y-m-d 23:59:59");
            }
            // >>> 关键修改点3 结束 <<<
            
            // 判断是否处于搜索模式 (只要有搜索框内容、ID筛选、或日期时间范围，即视为搜索模式)
            // >>> 关键修改点4: isSearching 的判断现在基于 filterStartDateStr 和 filterEndDateStr <<<
            const isSearching = !!query || !!selectedOriginalId || (filterStartDateStr && filterEndDateStr) || isHistoryMode; 
            
            let htmlOutput = '';
            let displayedIdNumbers = new Set(); // 用于统计唯一显示 ID (display_id_name)
            let totalActualDisplayedMessages = 0; // 页面实际渲染的消息卡片总数

            // 处理初始无数据状态
            if (Object.keys(allMessagesGroupedById).length === 0) {
                messagesContainer.innerHTML = '';
                displayedIdCountSpan.textContent = 0;
                displayedMessageCountSpan.textContent = 0;
                if (!isSearching) {
                    initialNoDataDiv.style.display = 'block';
                    noSearchResultsDiv.style.display = 'none';
                } else { // 即使无数据，但有搜索行为，也显示无搜索结果
                    initialNoDataDiv.style.display = 'none';
                    noSearchResultsDiv.style.display = 'block';
                }
                return;
            } else {
                initialNoDataDiv.style.display = 'none';
            }

            // 获取所有唯一的原始 ID 数组并按字符串排序
            const sortedOriginalIds = Object.keys(allMessagesGroupedById).sort();

            for (const originalId of sortedOriginalIds) { 
                // 如果有ID筛选，且当前ID不匹配，则跳过
                if (selectedOriginalId && originalId !== selectedOriginalId) {
                    continue;
                }

                const messagesForOriginalId = allMessagesGroupedById[originalId];
                if (!messagesForOriginalId || messagesForOriginalId.length === 0) continue;

                let messagesHtmlForCurrentIdGroup = '';
                let matchedMessagesCountForCurrentId = 0; // 记录当前ID下匹配搜索条件的消息数
                
                // 获取当前ID的display_id_name，使用最新一条消息的display_id_name
                // 消息已按接收时间倒序排列，messagesForOriginalId[0] 始终是最新
                const currentDisplayIdName = messagesForOriginalId[0].display_id_name;
                const totalMessagesForId = messagesForOriginalId.length;

                if (isSearching || isHistoryMode) {
                    // 搜索模式 或 历史模式：遍历该 ID 下的所有历史消息
                    for (const msg of messagesForOriginalId) {
                        // >>> 关键修改点5: 调用 messageMatchesDateRange 时传入两个独立的日期字符串 <<<
                        if (messageMatchesDateRange(msg, filterStartDateStr, filterEndDateStr) && messageMatchesQuery(msg, lowerCaseQuery)) {
                            messagesHtmlForCurrentIdGroup += createMessageCardHtml(
                                originalId, 
                                msg, 
                                query,          // 传递原始query用于高亮
                                true,           // 搜索模式下，卡片默认展开
                                true,           // isHistoryView: true (显示所有历史)
                                totalMessagesForId // 传递总消息数给卡片内的查看历史按钮判断
                            );
                            matchedMessagesCountForCurrentId++;
                            totalActualDisplayedMessages++;
                        }
                    }
                } else {
                    // 非搜索模式：只显示最新一条消息
                    const latestMsg = messagesForOriginalId[0]; // 消息已按时间倒序排列，第一个就是最新
                    if (latestMsg) {
                        messagesHtmlForCurrentIdGroup += createMessageCardHtml(
                            originalId, 
                            latestMsg, 
                            query,          // 即使没有搜索，也要传递query给highlightText，它会处理空query
                            false,          // 非搜索模式下，卡片默认折叠
                            false,          // isHistoryView: false (主页)
                            totalMessagesForId // 传递总消息数给卡片内的查看历史按钮判断
                        );
                        // 在非搜索模式下，这里只显示最新一条，所以实际渲染的消息数+1
                        totalActualDisplayedMessages++; 
                        // matchedMessagesCountForCurrentId 不需要在这里更新，因为非搜索模式下不显示这个统计
                    }
                }

                // 如果当前 ID 分组有消息需要显示
                if (messagesHtmlForCurrentIdGroup) {
                    displayedIdNumbers.add(currentDisplayIdName); // 统计唯一的 display_id_name

                    let headerCountText = '';
                    if (isSearching || isHistoryMode) {
                        headerCountText = `匹配 ${matchedMessagesCountForCurrentId} 条`;
                    } else {
                        headerCountText = `共 ${totalMessagesForId} 条`;
                    }
                    const idGroupHeaderContent = `<div>ID: <span class="id-text">${highlightText(currentDisplayIdName, query)}</span> (${headerCountText})</div>`;

                    // ID 分组的折叠图标和内容区域的默认状态
                    const idGroupToggleIconClass = `id-group-toggle-icon ${isSearching || isHistoryMode ? '' : 'rotated'}`; // 搜索/历史模式默认展开，非搜索模式默认折叠
                    const idGroupContentClass = `id-group-content ${isSearching || isHistoryMode ? '' : 'collapsed'}`; // 搜索/历史模式默认展开，非搜索模式默认折叠

                    htmlOutput += `
                        <div class="id-group">
                            <div class="id-group-header">
                                ${idGroupHeaderContent}
                                <span class="${idGroupToggleIconClass}">▼</span>
                            </div>
                            <div class="${idGroupContentClass}">
                                ${messagesHtmlForCurrentIdGroup}
                            </div>
                        </div>
                    `;
                }
            }

            messagesContainer.innerHTML = htmlOutput;

            // 根据是否有实际显示的消息以及是否处于搜索模式来显示提示
            if (totalActualDisplayedMessages === 0 && isSearching) { 
                noSearchResultsDiv.style.display = 'block';
            } else {
                noSearchResultsDiv.style.display = 'none';
                // 确保在内容渲染后绑定事件
                bindCardToggleEvents();    // 绑定消息卡片的折叠事件
                bindIdGroupToggleEvents(); // 绑定 ID 分组的折叠事件
                bindViewHistoryEvents();   // 绑定查看历史按钮事件
            }

            displayedIdCountSpan.textContent = displayedIdNumbers.size;
            // 默认情况下，显示所有历史消息的总条数
            if (!isSearching && !isHistoryMode) {
                // 如果是“全部时间”的默认显示，且没有其他搜索条件，显示所有消息总数
                // 重新计算总消息数，因为 allMessagesGroupedById 可能不是所有消息的精确计数
                let totalCount = 0;
                for (const id in allMessagesGroupedById) {
                    totalCount += allMessagesGroupedById[id].length;
                }
                displayedMessageCountSpan.textContent = totalCount;
            } else {
                displayedMessageCountSpan.textContent = totalActualDisplayedMessages;
            }
            console.log(`--- renderMessages finished --- Displayed ID Groups: ${displayedIdNumbers.size}, Total Messages Rendered: ${totalActualDisplayedMessages}`);
        }

        // 绑定搜索和日期时间过滤器的事件
        searchQueryInput.addEventListener('input', () => renderMessages());
        searchIdNumberSelect.addEventListener('change', () => renderMessages());
        // receiveTimeRangeInput.addEventListener('change', renderMessages); // Flatpickr 会通过其 onChange 回调触发 renderMessages
        
    </script>
{% endblock %}
